const router=require('koa-router')();
const koaBody=require('koa-body');
const events=require('events');
const config=require('../config/config');
const {Post,User,Comment,Message}=require('../models/index');
const redis=require('../models/redis.server.model');
const checkLogin=require('../middlewares/checkLogin');
const checkId=require('../middlewares/checkId');
const timeLimit=require('../middlewares/timeLimit');

//发表评论
router.post('/:postId/:action/:toId/',checkLogin(),checkId(['postId','toId']),timeLimit({action:'comment'}),koaBody(), async ctx=>{
    let {postId,action,toId}=ctx.params,{loginUser}=ctx.session,{content}=ctx.request.body,ee=new events(),atUser;
    ee.on('fail',msg=>{
        console.log('评论错误：\n',msg);
        ctx.falsh={error:msg};
        ctx.redirect('back');
    });

    if(!content || content.trim().length<config.characterLengthLimit.post.comment[0] || content.trim().length>config.characterLengthLimit.post.comment[1])return ee.emit('fail',`评论内容长度非法(${config.characterLengthLimit.post.comment[0]}~${config.characterLengthLimit.post.comment[1]})`);

    let findTasks=[
        User.findOne({_id:loginUser._id},{name:true}),
        Post.findOne({_id:postId},{title:true,author:true}),
    ];

    if('at'==action){
        content=content.replace(/^@\w+\b\s*/,'');
        findTasks.push(Comment.findOne({_id:toId},{author:true}));
    }

    let [user,post,to]=await Promise.all(findTasks);

    if(!user || !post)return ee.emit('fail','用户或话题不存在');
    if('at'==action){
        if(!to)return ee.emit('fail','评论不存在');
        atUser=await User.findOne({_id:to.author},{name:true});
    }else if('reply'==action){
        to=post;//评论的是话题
    }else{
        return ee.emit('fail','参数错误');
    }

    let newComment=new Comment({
        post:postId,
        author:ctx.session.loginUser,
        content,
        atUser,
        time:new Date()
    });
    let tasks=[
        newComment.save(),
        Post.update({_id:postId},{$push:{comments:newComment._id}}),
        User.update({_id:user._id},{$inc:{score:config.score.comment}}),
        redis.addLimit({action:'comment',id:user._id})
    ];
    if(loginUser._id!=to.author.toString()){//评论非自己的话题/评论，向话题作者/评论者写入“未读信息”
        tasks.push(new Message({from:{_id:user._id,name:user.name},to:to.author,action,post:{_id:post._id,title:post.title},commentId:newComment._id,time:new Date()}).save());
    }
    await Promise.all(tasks);
    ctx.session.loginUser.score+=config.score.comment;

    ctx.flash={success:'评论成功'};
    ctx.redirect('back');
});

//赞评论
router.post('/up/:id',checkLogin(),checkId(),koaBody(),async ctx=>{
    let {id}=ctx.params,{loginUser}=ctx.session,{action}=ctx.request.body,ee=new events();
    ee.on('fail',msg=>{
        ctx.body={
            code:404,
            msg
        }
    });
    ee.on('success',(msg,action)=>{
        ctx.body={
            code:200,
            msg,
            action
        }
    });

    let user=User.findOne({_id:loginUser._id},{_id:true});
    if(!user)return ee.emit('fail','用户或评论不存在');

    if('up'==action){
        let ret=await Comment.update({_id:id},{$addToSet:{ups:loginUser._id}});
        if(ret&&ret.n)return ee.emit('success','点赞成功',action);
        ee.emit('fail','此评论不存在');
    }else if('de_up'==action){
        let ret=await Comment.update({_id:id},{$pull:{ups:loginUser._id}});
        if(ret&&ret.n)return ee.emit('success','取消点赞成功',action);
        ee.emit('fail','此评论不存在');
    }
});

//编辑评论
router.get('/edit/:id',checkLogin(),checkId(),koaBody(),async ctx=>{
    let {id}=ctx.params,{loginUser}=ctx.session,ee=new events;
    ee.on('fail',msg=>{
       ctx.flash={error:msg};
       ctx.redirect('back');
    });
    let [comment,user]=await Promise.all([
        Comment.findOne({_id:id}),
        User.findOne({_id:loginUser._id})
    ]);
    if(!comment || !user)return ee.on('fail','用户或评论不存在');
    if(comment.author.toString() != user._id.toString())return ee.emit('fail','无权限');

    await ctx.render('editComment',{
        title:'编辑评论',
        success:ctx.flash.success,
        error:ctx.flash.error,
        loginUser,
        comment,
        postCharacterLengthLimit:config.characterLengthLimit.post
    });
});

//保存编辑评论
router.post('/edit/:id',checkLogin(),checkId(),timeLimit({action:'editComment'}),koaBody(), async ctx=>{
    let {id}=ctx.params,{loginUser}=ctx.session,{content,atUserId}=ctx.request.body,ee=new events(),atUser;
    ee.on('fail',msg=>{
        ctx.falsh={error:msg};
        ctx.redirect('back');
    });

    if(!content || content.trim().length<config.characterLengthLimit.post.comment[0] || content.trim().length>config.characterLengthLimit.post.comment[1])return ee.emit('fail',`评论内容长度非法(${config.characterLengthLimit.post.comment[0]}~${config.characterLengthLimit.post.comment[1]})`);
    if(atUserId){
        atUser=await User.findOne({_id:atUserId},{name:true});
        if(atUserId!=atUser._id.toString()){
            atUser=void 0;
        }
        content=content.replace(/^@\w+\b\s*/,'');
    }

    let comment=await Comment.findOne({_id:id},{_id:true,post:true,author:true});
    if(!comment)return ee.emit('fail','评论不存在');
    if(comment.author.toString()!=loginUser._id)return ee.emit('fail','无权限');

    let ret=await Promise.all([
        Comment.update({_id:id},{content,atUser}),
        redis.addLimit({action:'editComment',id:ctx.session.loginUser._id})
    ]);
    if(!ret || !ret[0].n ||!ret[1])return ee.emit('fail','保存Comment错误');
    ctx.flash={success:'保存编辑评论成功'};
    ctx.redirect('/article/'+comment.post);
});

//删除评论
router.get('/remove/:id',checkLogin(),checkId(),async ctx=>{
    let {id}=ctx.params,{loginUser}=ctx.session,ee=new events();
    ee.on('fail',msg=>{
        ctx.falsh={error:msg};
        ctx.redirect('back');
    });

    let [comment,user]=await Promise.all([
        Comment.findOne({_id:id},{author:true,post:true}),
        User.findOne({_id:loginUser._id},{_id:true})
    ]);

    if(!user || !comment)return ee.emit('fail','用户或评论不存在');

    if(comment.author.toString()!=loginUser._id)return ee.emit('fail','无权限');
    let ret=await Promise.all([
        Comment.remove({_id:id}),
        Post.update({_id:comment.post},{$pull:{comments:id}}),
        User.update({_id:user._id},{$inc:{score:-5}})
    ]);

    if(ret&&ret[0]&&ret[0].result.n){
        ctx.session.loginUser.score-=config.score.comment;
        ctx.body={
            code:200,
            msg:'删除评论成功'
        };
    }else{
        ctx.body={
            code:500,
            msg:'删除评论失败'
        };
    }
});

module.exports=router;